

abstract class Student {
  public abstract PrepareEx(): void
  public abstract PourReagent(): void
  public abstract PourCarbon(): void
  public abstract ShowResult(): void
}

class Student_A extends Student {
  // 实验前准备
  PrepareEx() {
    console.log('1-学生A准备了实验器材')
  }

  // 向烧杯添加氢氧化钡溶液
  PourReagent() {
    console.log('2-学生A将氢氧化钡溶液倒入烧杯')
  }

  // 向溶液中倒入二氧化碳气体
  PourCarbon() {
    console.log('3-学生A将“少量”二氧化碳气体通入氢氧化钡中')
  }

  ShowResult() {
    console.log('4-溶液中出现沉淀')
  }
}

class Student_B extends Student {
  // 实验前准备
  PrepareEx() {
    console.log('1-学生 B 准备了实验器材')
  }

  // 向烧杯添加氢氧化钡溶液
  PourReagent() {
    console.log('2-学生 B 将氢氧化钡溶液倒入烧杯')
  }

  // 向溶液中倒入二氧化碳气体
  PourCarbon() {
    console.log('3-学生 B 将“大量”二氧化碳气体通入氢氧化钡中')
  }

  ShowResult() {
    console.log('4-溶液中出现沉淀又消失')
  }
}

/**
 * student1 缺少了步骤
 * student2 步骤顺序出错
 */
// (function () {
//   let student1: Student_A = new Student_A()
//   let student2: Student_B = new Student_B()

//   student1.PourReagent()
//   student1.PourCarbon()

//   student1.ShowResult()

//   student2.PrepareEx()
//   student2.PourCarbon()
//   student2.PourReagent()

//   student2.ShowResult()
// }())

/**
 * 抽象建造者
 */
class Teacher {
  private student: Student

  constructor(student: Student) {
    this.student = student
  }

  DirectExperiment() {
    this.student.PrepareEx()
    this.student.PourReagent()
    this.student.PourCarbon()
    this.student.ShowResult()
  }
}

(function () {
  let student1: Student_A = new Student_A()
  let student2: Student_B = new Student_B()

  // 指导实验A
  let teacher: Teacher = new Teacher(student1)
  teacher.DirectExperiment()

  // 指导实验A
  teacher = new Teacher(student2)
  teacher.DirectExperiment()

}())